package org.bes.WinClass;

import org.bes.api.IDelete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.json.JsonArray;
import javax.json.JsonValue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;

public class FileDelete extends PatchInfo implements IDelete {
    private static final Logger log = LoggerFactory.getLogger(FileDelete.class);
    Path tmpDir = Paths.get(System.getProperty("user.dir")).resolve("tmp");
    Path tmpNewFileDir = Paths.get(System.getProperty("user.dir")).resolve("tmpNewFile");

    public static void deleteFile(File file){

        try {
            if(file.exists()){
                Files.delete(file.toPath());
            } else {
                log.warn("delete file not exist");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void delete() {
        System.out.println("Deleting tmp and tmpNewFile folders");
        if (tmpDir.toFile().exists()) {
            deleteDirectory(tmpDir);
        } else{
            System.out.println("tmp folder does not exist");
        }

        if (tmpNewFileDir.toFile().exists()) {
            deleteDirectory(tmpNewFileDir);
        } else {
            System.out.println("tmpNewFile folder does not exist");
        }
    }

    //递归删除tmp及tmpNewFile文件夹的内容
    public void deleteDirectory(Path directory) {

        if (directory.toFile().exists()) {
            File[] files = directory.toFile().listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteDirectory(file.toPath());
                    } else {
                        file.delete();
                    }
                }
            }
            directory.toFile().delete();

        }
    }

    static void deleteClassesFromJar(File jarFile, JsonArray deleteClasses) {
        try {
            // Create a temporary file to store the modified JAR
            File tempJarFile = File.createTempFile("temp_", ".jar");
            tempJarFile.deleteOnExit();

            // Open the original JAR file and the temporary file
            try (JarFile originalJar = new JarFile(jarFile);
                 JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(tempJarFile))) {

                Enumeration<JarEntry> entries = originalJar.entries();

                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    boolean shouldDelete = false;

                    // Check if the class file needs to be deleted
                    for (JsonValue classToDelete : deleteClasses) {
                        if (entry.getName().equals(classToDelete.toString().replace("\"", ""))) {
                            shouldDelete = true;
                            break;
                        }
                    }

                    // If the entry is not a class file to be deleted, copy it to the new JAR
                    if (!shouldDelete) {
                        jarOutputStream.putNextEntry(new JarEntry(entry.getName()));
                        try (InputStream entryStream = originalJar.getInputStream(entry)) {
                            byte[] buffer = new byte[1024];
                            int length;
                            while ((length = entryStream.read(buffer)) > 0) {
                                jarOutputStream.write(buffer, 0, length);
                            }
                        }
                        jarOutputStream.closeEntry();
                    }
                }
            }

            // After all files are copied, replace the original JAR with the modified one

            try {
                Files.move(tempJarFile.toPath(), jarFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                log.info("Temp JAR file successfully renamed to original name: {}", jarFile.getAbsolutePath());
            } catch (IOException e) {
                log.error("Error replacing JAR file: {}", e.getMessage());
            }

        } catch (IOException e) {
            log.error("Error processing JAR file: {}", jarFile.getAbsolutePath(), e);
        }
    }
}
